/*
 * @Author: TLL
 * @Date: 2021-07-20 13:08:53
 * @version: v1.1
 * @Descripttion:
 * @LastEditors: Please set LastEditors
 * @LastEditTime: 2021-09-15 17:29:52
 * @Auditor: TLL
 */
import React, { useCallback, useEffect, useState } from 'react';
import { DragDropContext, Droppable, Draggable } from 'react-beautiful-dnd';
import { Checkbox } from 'antd';
import style from './style.module.scss';

const reorder = (list: any, startIndex: any, endIndex: any) => {
  const result = Array.from(list);
  const [removed] = result.splice(startIndex, 1);
  result.splice(endIndex, 0, removed);
  return result;
};

const move = (source: any, destination: any, droppableSource: any, droppableDestination: any) => {
  const sourceClone = Array.from(source);
  const destClone = Array.from(destination);
  const [removed] = sourceClone.splice(droppableSource.index, 1);
  destClone.splice(droppableDestination.index, 0, removed);
  const result = {};
  result[droppableSource.droppableId] = sourceClone;
  result[droppableDestination.droppableId] = destClone;
  return result;
};

const getItemStyle = (isDragging: any, draggableStyle: any) => ({
  userSelect: 'none',
  paddingBottom: '2px',
  marginBottom: '2px',
  background: isDragging ? '#eee' : '#fff',
  ...draggableStyle,
});

const getListStyle = (isDraggingOver: any) => ({
  padding: '2px',
  width: 250,
  overflow: 'auto',
});

const dropMap = {
  droppable: 'items',
  droppable2: 'selected',
};

const CheckboxComp = ({ item, handleResult }: any) => {
  const [checked, setChecked] = useState(false);

  useEffect(() => {
    setChecked(item.checked);
  }, [item]);

  const changeChecked = useCallback(
    (e: any) => {
      const bool = e.target?.checked;
      item.checked = e.target?.checked;
      setChecked(bool);
      handleResult?.();
    },
    [item, handleResult]
  );

  return (
    <Checkbox checked={checked} onChange={changeChecked}>
      {localStorage.i18nextLng === 'en' ? (item?.titleEn || item.title) : item?.title}
    </Checkbox>
  );
};

interface Props {
  columns: any;
  handleResult: any;
  handleChildren?: (item: any, index: number) => JSX.Element;
}

const _DropDragColumns = ({ columns, handleResult, handleChildren }: Props) => {
  const [items, setItems] = useState<any>([]);
  const [selected, setSelected] = useState<any>([]);

  useEffect(() => {
    if (columns?.length) setItems(columns);
  }, [columns]);

  const getList = (id: any) => {
    if (dropMap[id] === 'items') return items;
    return selected;
  };

  const onDragEnd = (res: any) => {
    const { source, destination } = res;
    if (!destination) return;
    let result: any;
    if (source.droppableId === destination.droppableId) {
      result = reorder(getList(source.droppableId), source.index, destination.index);
      if (source.droppableId === 'droppable') setItems(result);
      if (source.droppableId === 'droppable2') setSelected(result);
    } else {
      result = move(getList(source.droppableId), getList(destination.droppableId), source, destination);
      setItems(result.droppable);
      setSelected(result.droppable2);
    }
    handleResult?.(result);
  };

  return (
    <>
      <DragDropContext onDragEnd={(result) => onDragEnd(result)}>
        <Droppable droppableId="droppable">
          {(provided: any, snapshot: any) => (
            <div ref={provided.innerRef} style={getListStyle(snapshot.isDraggingOver)}>
              {items.map((item: any, index: number) => (
                <Draggable key={item.dataIndex} draggableId={item.dataIndex} index={index}>
                  {(provided: any, snapshot: any) => (
                    <div
                      ref={provided.innerRef}
                      {...provided.draggableProps}
                      {...provided.dragHandleProps}
                      style={getItemStyle(snapshot.isDragging, provided.draggableProps.style)}
                    >
                      <div className={style.columnItemContainer}>
                        <CheckboxComp item={item} handleResult={handleResult} />
                        {handleChildren && handleChildren?.(item, index)}
                      </div>
                    </div>
                  )}
                </Draggable>
              ))}
              {provided.placeholder}
            </div>
          )}
        </Droppable>
        <Droppable droppableId="droppable2">
          {(provided: any, snapshot: any) => (
            <div ref={provided.innerRef} style={getListStyle(snapshot.isDraggingOver)}>
              {selected.map((item: any, index: any) => (
                <Draggable key={item.dataIndex} draggableId={item.dataIndex} index={index}>
                  {(provided: any, snapshot: any) => (
                    <div
                      ref={provided.innerRef}
                      {...provided.draggableProps}
                      {...provided.dragHandleProps}
                      style={getItemStyle(snapshot.isDragging, provided.draggableProps.style)}
                    >
                      {item.title}
                    </div>
                  )}
                </Draggable>
              ))}
              {provided.placeholder}
            </div>
          )}
        </Droppable>
      </DragDropContext>
    </>
  );
};

export default _DropDragColumns;
